#include "sc.h"
#include "globals.h"

NeighbourhoodToPixelOp()
interpolate(in stream unsigned char i[-1..0][-1..0],
	 out stream unsigned char *o)
{
  *o = i[-1][0]*0.24 + i[-1][-1]*0.24 + i[0][-1]*0.24 + i[0][0]*0.24;
}

NeighbourhoodToPixelOp()
sobelx(in stream unsigned char i[-1..1][-1..1],
       out stream short int *o)
{
  int x, y;
  short temp;
  
  temp = 0;
  for (y=-1; y < 2; y++)
    for (x=-1; x < 2; x=x+2)
      temp = temp + x*i[y][x];

  *o = temp;
}

NeighbourhoodToPixelOp()
sobely(in stream unsigned char i[-1..1][-1..1],
       out stream short int *o)
{
  int x, y;
  short int temp;
  
  temp = 0;
  for (x=-1; x < 2; x++)
    for (y=-1; y < 2; y=y+2)
      temp = temp + y*i[y][x];

  *o = temp;
}

PixelToPixelOp()
magnitude(in stream short int *i1,
  	  in stream short int *i2,
	  out stream unsigned char *o)
{
  short int temp;

  *o = IABS(*i1)+IABS(*i2);
}

PixelToPixelOp()
binarize(in stream unsigned char *i,
	 out stream unsigned char *o)
{
  *o = (*i>128)?192:(*i>64)?64:0;
}

PixelToPixelOp()
add(in stream unsigned char *i1, in stream unsigned char *i2,
	out stream unsigned char *o)
{
  *o = *i1 + *i2;
}

NeighbourhoodToPixelOp()
sobel(in stream unsigned char i[-1..1][-1..1],
      out stream short int *o1, out stream short int *o2)
{
  int x, y;
  short int sx, sy;
 
  sx = 0;
  for (y=-1; y < 2; y++)
    for (x=-1; x < 2; x=x+2)
      sx = sx + x*i[y][x];
  sy = 0;
  for (x=-1; x < 2; x++)
    for (y=-1; y < 2; y=y+2)
      sy = sy + y*i[y][x];

  *o1 = sx;
  *o2 = sy;
}


NeighbourhoodToPixelOp()
magbin(in stream short int i1[0][0], in stream short int i2[0][0],
       out stream unsigned char *o)
{
  unsigned char mag;

  mag = IABS(i1[0][0]) + IABS(i2[0][0]);

  *o = (mag>128)?192:(mag>64)?64:0;
}                      

OptStackOp(in int *threshold=scint(0))
propagation(in stream unsigned char i[-1..1][-1..1],
            out stream unsigned char *o)
{  
  int x, y;
  unsigned char *item;

  if (*o != 255)
  {
    *o = 255;

    for (y=-1; y < 2; y++)
      for (x=-1; x < 2; x++)
	if (y != 0 || x != 0)
        {
          item = &i[y][x];
 
	  if (*item == 64)
	    addtostack(item);
        }
  }
}

PixelToPixelOp()
split(in stream unsigned char *i, out stream unsigned char *o1, out stream unsigned char *o2)
{
  *o1 = *i;
  *o2 = *i;
}

NeighbourhoodToPixelOp()
splitline(in stream unsigned char i[0..0][0..0],
	  out stream unsigned char *o1, out stream unsigned char *o2)
{
  *o1 = i[0][0];
  *o2 = i[0][0];
}

NeighbourhoodToPixelOp()
edgebin(in stream unsigned char i[-1..1][-1..1], out stream unsigned char *o)
{
  int x, y;
  short int sx, sy;
  unsigned char mag;
 
  sx = 0;
  for (y=-1; y < 2; y++)
    for (x=-1; x < 2; x=x+2)
      sx = sx + x*i[y][x];
  sy = 0;
  for (x=-1; x < 2; x++)
    for (y=-1; y < 2; y=y+2)
      sy = sy + y*i[y][x];

  mag = IABS(sx) + IABS(sy);

  *o = (mag>128)?192:(mag>64)?64:0;
}

#ifdef PSOS  
#include "scxtl.h"
extern tmr_t frameTime;
#define MAINPROTO(x) MAIN(void)
#define argc _argc
#define argv _argv
#define LOGINIT() liblog_init()
#else
#define MAINPROTO(x) MAIN(int argc, char **argv)
#define LOGINIT()
#endif

int MAINPROTO(void)
{
  int i=0, dummy;
  STREAM a, b, c;
  char text[255];

  /* Assemble command line */
  int _argc=8;
  char *_argv[8] = {"sctest", "-n", "TriMedia", "-m", "/flash/machines", "-a", "/flash/availability.txt", "-c"};

  LOGINIT();

  scInit(argc, argv);

#ifndef PSOS
  i = 20;
#endif

  while (1)
  {
    sprintf(text, "Xetal (%d)                     ", i%10);
    SC_OUTPUT_BUFSIZE = 64*640;
    capture(&a);
    interpolate(&a, &a);
    edgebin(&a, &a);
/*

    switch ((i/10)%5)
    {
      case 0:
      case 1:
        switch ((i/10)%5)
        {
          case 0:              
            sprintf(text, "Unmerged, 4-line bufs (%d)         ", i%10);
            SC_OUTPUT_BUFSIZE = 4*640;
            break;
          case 1:
            sprintf(text, "Unmerged, 64-line bufs (%d)         ", i%10);
    	    SC_OUTPUT_BUFSIZE = 64*640;
    	    break;
    	}

	capture(&a);
	dummy = 0;	
	interpolate(&a, &a);
	dummy = 0;	
	sobelx(&a, &b);
	dummy = 0;	
	sobely(&a, &a);
	dummy = 0;	
	magnitude(&a, &b, &a);
	dummy = 0;
	_finalize(&b);
	dummy = 0;
	binarize(&a, &a);
	dummy = 0;
	break;

      case 2:
        sprintf(text, "Merged (%d)                     ", i%10);
	SC_OUTPUT_BUFSIZE = 64*640;

	capture(&a);
	interpolate(&a, &a);
	splitline(&a, &a, &b);
	sobelx(&a, &a);
	sobely(&b, &b);
	dummy = 0;
	magnitude(&a, &b, &a);
	_finalize(&b);
	binarize(&a, &a);
	break;	

      case 3:
        sprintf(text, "Handpixel merged (%d)       ", i%10);
	SC_OUTPUT_BUFSIZE = 64*640;

	capture(&a);
	interpolate(&a, &a);
	splitline(&a, &a, &b);
	sobelx(&a, &a);
	sobely(&b, &b);
 	sobel(&a, &a, &b);
	magbin(&a, &b, &a);
	_finalize(&b);
	break;	

      case 4:

        sprintf(text, "Handcoded (%d)                     ", i%10);
	SC_OUTPUT_BUFSIZE = 64*640;
	capture(&a);
	interpolate(&a, &a);
	edgebin(&a, &a);
	break;	
    }
*/

    OptStackOp(scint(128), propagation, &a, &a);
    display(&a);
    _block(&a);

#ifdef PSOS
    tmrStop(&frameTime);
    xtlDrawFrameTime(tmrGetValueInUs(&frameTime), text);
#endif

    i = i + 1;
    
#ifndef PSOS
    break;
#endif
  }

  return scExit();
}
